package com.fastjars.business.upload;

import com.fastjars.business.upload.hunter.FileManager;
import com.fastjars.business.upload.hunter.ImageHunter;
import org.apache.commons.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * ActionHandler
 *
 * @author Brant Liu <br> 邮箱：<br>lbf1988@qq.com <br>日期：<br>2018/04/16
 * @version 1.0.0
 */
public class ActionHandler {
    public final static String FILE_SEPARATOR  = "/";
    public final static String FILE_BACKSLASH  = "\\";
    public final static String PARAM_ACTION    = "action";
    public final static String PARAM_SAVE_PATH = "savePath";
    public final static String PARAM_ROOT_PATH = "rootPath";
    public final static String PARAM_CALLBACK  = "callback";
    public final static String PARAM_START     = "start";
    private HttpServletRequest request = null;
    private String rootPath = null;
    private String action = null;
    private String contextPath = null;
    private ConfigManager configManager = null;

    public ActionHandler(HttpServletRequest request) {
        this(request, null);
    }

    /**
     * @param request
     * @param rootPath 如果为空，默认为当前WEB根目录
     */
    public ActionHandler(HttpServletRequest request, String rootPath) {
        this.request = request;
        if (StringUtils.isBlank(rootPath)) {
            // TODO: 2018/04/16 如果为空设置为当前网站根目录
            rootPath = request.getSession().getServletContext().getRealPath(FILE_SEPARATOR);
        }
        this.rootPath = rootPath;
        // TODO: 2018/04/16 获取当前操作类型
        this.action = request.getParameter(PARAM_ACTION);
        if(StringUtils.isBlank(this.action)){
            // TODO: 2018/04/16 默认上传文件事件
            this.action = Action.ACTION_DEFAULT_UPLOAD_FILE;
        }
        this.contextPath = request.getContextPath();
        this.configManager = ConfigManager.me(this.rootPath, this.contextPath, request.getRequestURI());
    }

    public Object execute(){
        return this.execute(null);
    }

    /**
     * 执行资源处理程序
     * @param beforeHandler
     * @return 返回ActionResult或者经过jsonp处理的Object
     */
    public Object execute(ActionResultBeforeHandler beforeHandler){
        String callbackName = this.request.getParameter(PARAM_CALLBACK);
        if(!StringUtils.isBlank(callbackName)){
            if (!validCallbackName(callbackName)) {
                return new ActionResult(ActionState.ILLEGAL);
            }
            Object result = this.handlerProcess();
            beforeHandlerResult(beforeHandler, result);
            return callbackName + "(" + result + ");";
        }
        Object result = this.handlerProcess();
        beforeHandlerResult(beforeHandler,result);
        return result;
    }

    /**
     * 返回前处理
     * @param beforeHandler
     * @param result
     */
    protected void beforeHandlerResult(ActionResultBeforeHandler beforeHandler, Object result){
        if(null != beforeHandler && result instanceof ActionResult) {
            if (null != result && ActionState.getStateInfo(ActionState.SUCCESS).equals(((ActionResult) result).getState())) {
                beforeHandler.before((ActionResult) result);
            }
        }
    }

    public Object handlerProcess(){
        if (!Action.mapping.containsKey(this.action)) {
            return new ActionResult(ActionState.INVALID_ACTION);
        }
        if (this.configManager == null || !this.configManager.valid()) {
            return new ActionResult(ActionState.CONFIG_ERROR);
        }
        ActionResult result = null;

        int actionCode = Action.getType(this.action);
        Map<String, Object> conf = null;

        switch (actionCode) {
            case Action.CONFIG:
                return this.configManager.getAllConfig();
            case Action.UPLOAD_IMAGE:
            case Action.UPLOAD_SCRAWL:
            case Action.UPLOAD_VIDEO:
            case Action.UPLOAD_FILE:
            case Action.UPLOAD_ADDON:{
                conf = this.configManager.getConfig(actionCode);
                if ("true".equals(conf.get("isBase64"))) {
                    result = ResourceUploader.saveBase64(this.request, conf);
                } else {
                    result = ResourceUploader.saveBinary(this.request, conf);
                }
            }break;
            case Action.CATCH_IMAGE:{
                conf = configManager.getConfig(actionCode);
                String[] list = this.request.getParameterValues((String) conf.get("fieldName"));
                result = new ImageHunter(conf).capture(list);
            }break;
            case Action.LIST_IMAGE:
            case Action.LIST_FILE:{
                conf = configManager.getConfig(actionCode);
                int start = this.getStartIndex();
                result = new FileManager(conf).listFile(start);
            }break;
        }
        if (null != result && ActionState.getStateInfo(ActionState.SUCCESS).equals(result.getState())) {
            result.setRootPath(this.rootPath);
            result.setAction(actionCode);
        }
        return result;
    }

    /**
     * 获取列表开始页码
     * @see Action#LIST_FILE
     * @see Action#LIST_IMAGE
     * @return 返回开始页码
     */
    public int getStartIndex() {
        String start = this.request.getParameter(PARAM_START);
        try {
            return Integer.parseInt(start);
        } catch (Exception e) {
            return 0;
        }
    }

    /**
     * callback参数验证
     */
    public boolean validCallbackName(String name) {
        if (name.matches("^[a-zA-Z_]+[\\w0-9_]*$")) {
            return true;
        }
        return false;
    }
}
